package com.idea.id_generate.rest;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.validation.Errors;

import java.io.Serializable;

/**
 * ResponseWrapper
 */
@Data
@EqualsAndHashCode
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class ResponseWrapper<T> implements Serializable {
    private static final long serialVersionUID = -1696727488987157682L;

    @JsonProperty("code")
    private int code;

    @JsonProperty("msg")
    private String message;

    @JsonProperty("data")
    private T data;

    public ResponseWrapper(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public static <T> ResponseWrapperBuilder<T> builder() {
        ResponseWrapperBuilder<T> builder = new ResponseWrapperBuilder<>();
        return builder;
    }

    public static <T> ResponseWrapperBuilder<T> success() {
        ResponseWrapperBuilder<T> builder = new ResponseWrapperBuilder<>();
        builder.code(ResponseCode.SUCCESS).data(null).setMessage("success");
        return builder;
    }

    public static <T> ResponseWrapperBuilder<T> success(T data) {
        ResponseWrapperBuilder<T> builder = new ResponseWrapperBuilder<>();
        builder.code(ResponseCode.SUCCESS).data(data).setMessage("success");
        return builder;
    }

    public static <T> ResponseWrapperBuilder<T> success(T data, String message) {
        ResponseWrapperBuilder<T> builder = new ResponseWrapperBuilder<>();
        builder.code(ResponseCode.SUCCESS).data(data).setMessage(message);
        return builder;
    }

    public static <T> ResponseWrapperBuilder<T> failed(T data) {
        ResponseWrapperBuilder<T> builder = new ResponseWrapperBuilder<>();
        builder.code(ResponseCode.FAILED).data(data);
        return builder;
    }

    public static <T> ResponseWrapperBuilder<T> exception(T data) {
        ResponseWrapperBuilder<T> builder = new ResponseWrapperBuilder<>();
        builder.code(ResponseCode.FAILED).data(data);
        return builder;
    }

    public static <T> ResponseWrapperBuilder<T> exception() {
        ResponseWrapperBuilder<T> builder = new ResponseWrapperBuilder<>();
        builder.code(ResponseCode.FAILED).data(null);
        return builder;
    }

    public static <T> ResponseWrapperBuilder<T> validationErrors(Errors errors) {
        ResponseWrapperBuilder<T> builder = new ResponseWrapperBuilder<>();
        StringBuffer errMessages = new StringBuffer();
        errors.getAllErrors().forEach(err -> errMessages.append(err.getDefaultMessage()).append(";"));
        builder.code(ResponseCode.FAILED).data(null).setMessage(errMessages.toString());
        return builder;
    }

    public static class ResponseWrapperBuilder<T> {
        private int code;
        private String message;
        private T data;

        public ResponseWrapperBuilder<T> code(int code) {
            this.code = code;
            return this;
        }

        public ResponseWrapperBuilder<T> setMessage(String message) {
            this.message = message;
            return this;
        }

        public ResponseWrapperBuilder<T> data(T data) {
            this.data = data;
            return this;
        }

        public ResponseWrapper<T> build() {
            return new ResponseWrapper<>(this.code, this.message, this.data);
        }
    }
}
